package tjs.study.notes.dotest.redis;

import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by Nicky.Tang on 2022/11/22 下午4:55
 *
 * @since 02.12.10
 */
public class 测试BitMap {
    private static final Logger logger = LoggerFactory.getLogger(测试BitMap.class);
    private static final Integer trueFlag = 1;

    public static final String HAS_SAME = "tjs:test:hasSame";
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * fixme samePeriodIds需要在上层调用方，分批处理
     * @param samePeriodIds 仅返回bitMap不存在true数据
     * @return
     */
    public Set<Long> getDifferentIds(List<Long> samePeriodIds) {
        Set<Long> res = new HashSet<>();
        try {
            BitFieldSubCommands commands = BitFieldSubCommands.create();
            for (Long samePeriodId : samePeriodIds) {
                commands = commands.get(BitFieldSubCommands.BitFieldType.unsigned(1)).valueAt(samePeriodId.intValue());
            }
            List<Long> resRedis = stringRedisTemplate.opsForValue().bitField(HAS_SAME, commands);
            for (int i = 0; i < resRedis.size(); i++) {
                if (!trueFlag.equals(resRedis.get(i).intValue())) {
                    res.add(samePeriodIds.get(i));
                }
            }
        } catch (Exception ex) {
            logger.error("", ex);
            res = Sets.newHashSet(samePeriodIds);
        }
        return res;
    }

    public void addHasSame(List<Long> samePeriodIds) {
        try {
            if (CollectionUtils.isEmpty(samePeriodIds)) {
                return;
            }
            BitFieldSubCommands commands = BitFieldSubCommands.create();
            for (Long samePeriodId : samePeriodIds) {
                commands = commands.set(BitFieldSubCommands.BitFieldType.unsigned(1)).valueAt(samePeriodId.intValue()).to(trueFlag);

            }
            stringRedisTemplate.opsForValue().bitField(HAS_SAME, commands);
        } catch (Exception ex) {
            logger.error("", ex);
        }
    }

}
